package com.koron.system.staff.service.impl;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.banboocloud.Codec.Sm4Cipher;
import com.koron.bean.system.staff.po.AppUserPo;
import com.koron.system.common.util.BamboocloudUtils;
import com.koron.system.staff.bean.UnifyStaffBean;
import com.koron.system.staff.bean.entity.AttributeEntity;
import com.koron.system.staff.bean.entity.ColumnEntity;
import com.koron.system.staff.bean.entity.GroupDepartment;
import com.koron.system.staff.bean.entity.GroupStaff;
import com.koron.system.staff.mapper.SchemaMapper;
import com.koron.system.staff.mapper.UnifyUserMapper;
import com.koron.system.staff.service.BimUnifyUserService;
import com.koron.system.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author jzp
 * @since 2023/6/29
 */
@Slf4j
@Transactional
@Service
public class BimUnifyUserServiceImpl implements BimUnifyUserService {
    private static final String key = "JLB6L6MJVIT5Z7IL";
    private static final String type = "SM4";
    private static final String signType = "SM3";
    Sm4Cipher sm4Cipher = new Sm4Cipher();

    private static final String bimRemoteUser = "GDH_EAM2";
    private static final String bimRemotePwd = "4975a29ce99d450";

    @Autowired
    private StaffService staffService;

    @Autowired
    UnifyUserMapper unifyUserMapper;

    @Autowired
    private SchemaMapper schemaMapper;

    @Override
    public String schemaService(HttpServletRequest req) {
        Map<String, Object> check = check(req);
        Map<String, Object> result = new HashMap<>();
        if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
            List<AttributeEntity> tabUser = getTableAttribute("s_group_staff");
            List<AttributeEntity> tabOrg = getTableAttribute("s_group_department");
            result.put("account",tabUser);
            result.put("organization", tabOrg);
            result.put("bimRequestId",check.get("bimRequestId"));
        }
        log.info(JSON.toJSONString(result));
        return sm4Cipher.encrypt(JSON.toJSONString(result), key);
    }

    @Override
    public String orgCreateService(HttpServletRequest req) {
        Map<String, Object> check = check(req);
        if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
            try {
                // ----------------------
                if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
                    GroupDepartment groupDepartment = new GroupDepartment();
                    List<AttributeEntity> tabOrg = getTableAttribute("s_group_department");
                    for (AttributeEntity attributeEntity : tabOrg) {
                        String columnName= attributeEntity.getName();
                        if (!check.containsKey(columnName)) {
                            continue;
                        }
                        Object value = check.get(columnName);
                        ReflectUtil.setFieldValue(groupDepartment, StrUtil.toCamelCase(columnName), value);
                    }
                    if (ObjectUtils.isEmpty(check.get("bimOrgId"))){
                        String uid = groupDepartment.getCode();
                        groupDepartment.setId(uid);
                        check.put("uid",uid);
                        log.info("从竹云新增组织：{}", groupDepartment.getId());
                        unifyUserMapper.insertGroupDepartment(groupDepartment);
                    }else {
                        groupDepartment.setId(check.get("bimOrgId").toString());
                        log.info("从竹云更新组织：{}", groupDepartment.getId());
                        unifyUserMapper.updateGroupDepartment(groupDepartment);
                    }
                }
            } catch (Exception e) {
                check.put("resultCode ", "500");
                check.put("message", "属性字段未正确对应！");
                throw new RuntimeException(e);
            }
        }
        return sm4Cipher.encrypt(JSON.toJSONString(check), key);
    }

    @Override
    public String orgDeleteService(HttpServletRequest req) {
        Map<String, Object> check = check(req);
        if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
            try {
                if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
                    GroupDepartment groupDepartment = new GroupDepartment();
                    List<AttributeEntity> tabOrg = getTableAttribute("s_group_department");
                    for (AttributeEntity attributeEntity : tabOrg) {
                        String columnName = attributeEntity.getName();
                        if (!check.containsKey(columnName)) {
                            continue;
                        }
                        Object value = check.get(columnName);
                        ReflectUtil.setFieldValue(groupDepartment, StrUtil.toCamelCase(columnName), value);
                    }
                    if (!ObjectUtils.isEmpty(check.get("bimOrgId"))){
                        groupDepartment.setId(check.get("bimOrgId").toString());
                    }
                    log.info("从竹云删除组织：{}", groupDepartment.getId());
                    unifyUserMapper.deleteOrgNode(groupDepartment.getId());
                }
            } catch (Exception e) {
                check.put("resultCode ", "500");
                check.put("message", "属性字段未正确对应！");
                throw new RuntimeException(e);
            }
        }
        return sm4Cipher.encrypt(JSON.toJSONString(check), key);
    }

    @Override
    public String userCreateService(HttpServletRequest req) {
        Map<String, Object> check = check(req);
        if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
            try {
                // ----------------------
                if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
                    GroupStaff groupStaff = new GroupStaff();
                    List<AttributeEntity> tabOrg = getTableAttribute("s_group_staff");
                    for (AttributeEntity attributeEntity : tabOrg) {
                        String columnName = attributeEntity.getName();
                        // 1. 不处理密码字段
                        if (!check.containsKey(columnName) || columnName.equals("password")) {
                            continue;
                        }
                        Object value = check.get(columnName);
                        // 字段处理和转化
                        // 2.特殊映射 account为bim系统关键字，不允许使用
                        if (columnName.equals("userAccount")){
                            columnName = "account";
                        }
                        // 3. 性别字段转化
                        if (columnName.equals("sex")) {
                            if ("男".equals(value)) {
                                value = "1";
                            } else if ("女".equals(value)) {
                                value = "2";
                            }
                        }
                        // 状态
                        if (columnName.equals("status")) {
                            if ("false".equals(value)) {
                                value = "1";
                            } else if ("true".equals(value)) {
                                value = "0";
                            }
                        }

                        ReflectUtil.setFieldValue(groupStaff, StrUtil.toCamelCase(columnName), value);
                    }
                    if (ObjectUtils.isEmpty(check.get("bimUid"))){
                        check.put("uid",groupStaff.getAccount());
                        log.info("从竹云新增用户：{}", groupStaff.getAccount());
                        if (StringUtils.isEmpty(groupStaff.getId())) {
                            groupStaff.setId(groupStaff.getAccount());
                        }
                        unifyUserMapper.insertGroupStaff(groupStaff);
                    }else {
                        if (check.containsKey("__ENABLE__")) {
                            Object value = check.get("__ENABLE__");
                            if ("false".equals(value)) {
                                groupStaff.setStatus(0);
                            } else if ("true".equals(value)) {
                                groupStaff.setStatus(1);
                            }
                        }
                        groupStaff.setId(check.get("bimUid").toString());
                        log.info("从竹云更新用户：{}", groupStaff.getId());
                        unifyUserMapper.updateGroupStaff(groupStaff);
                    }
                }
            } catch (Exception e) {
                check.put("resultCode ", "500");
                check.put("message", "属性字段未正确对应！");
                throw new RuntimeException(e);
            }
        }
        return sm4Cipher.encrypt(JSON.toJSONString(check), key);
    }

    @Override
    public String userDeleteService(HttpServletRequest req) {
        Map<String, Object> check = check(req);
        if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
            try {
                if (Integer.parseInt(String.valueOf(check.get("resultCode"))) == 0) {
                    GroupStaff groupStaff = new GroupStaff();
                    List<AttributeEntity> tabOrg = getTableAttribute("s_group_staff");
                    for (AttributeEntity attributeEntity : tabOrg) {
                        String columnName= attributeEntity.getName();
                        if (!check.containsKey(columnName)) {
                            continue;
                        }
                        Object value = check.get(columnName);
                        //特殊映射 account为bim系统关键字，不允许使用
                        if (columnName.equals("userAccount")){
                            columnName = "account";
                        }
                        ReflectUtil.setFieldValue(groupStaff, StrUtil.toCamelCase(columnName), value);

                    }
                    if (!ObjectUtils.isEmpty(check.get("bimUid"))){
                        groupStaff.setId(check.get("bimUid").toString());
                    }
                    log.info("从竹云删除用户：{}", groupStaff.getId());
                    unifyUserMapper.deleteStaffNode(groupStaff.getId());
                }
            } catch (Exception e) {
                check.put("resultCode ", "500");
                check.put("message", "属性字段未正确对应！");
                throw new RuntimeException(e);
            }
        }
        return sm4Cipher.encrypt(JSON.toJSONString(check), key);
    }

    private Map<String, Object> check(HttpServletRequest req) {
        String bodyparam = BamboocloudUtils.getRequestBody(req);
        log.info("first--param-->" + bodyparam);
        //报文解密
        bodyparam = BamboocloudUtils.getPlaintext(bodyparam, key, type);
        log.info("json--param-->" + bodyparam);
        Map<String, Object> map = JSONObject.parseObject(bodyparam);
        //验证签名
        if (BamboocloudUtils.verify(map, signType)) {
            String username = (String) map.get("bimRemoteUser");
            String password = (String) map.get("bimRemotePwd");
            if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password) && checkUsernamePassword(username, password)) {
                map.put("resultCode", "0");
                map.put("message", "success");
            } else {
                map.put("resultCode", "500");
                map.put("message", "账号校验失败！");
            }
        } else {
            map.put("resultCode", "500");
            map.put("message", "密钥校验失败！");
        }
        map.remove("bimRemoteUser");
        map.remove("bimRemotePwd");
        map.remove("signature");
        log.info("check后信息：{}", JSON.toJSONString(map));
        return map;
    }

    private boolean checkUsernamePassword(String username, String password) {
        return bimRemoteUser.equals(username) && bimRemotePwd.equals(password);
    }

    private List<AttributeEntity> getTableAttribute(String tableName) {
        List<AttributeEntity> tables = new ArrayList<>();
        try {
            String columType;
            List<ColumnEntity> columnEntityList = schemaMapper.selectListColumnByTableName(tableName);
            for (ColumnEntity columnEntity : columnEntityList) {
                switch (columnEntity.getDataType()) {
                    case "varchar":
                        columType = "String";
                        break;
                    case "int":
                    case "tinyint":
                    case "char":
                        columType = "Integer";
                        break;
                    case "datetime":
                        columType = "Date";
                        break;
                    default:
                        columType = "String";
                }
                AttributeEntity attributeEntity = new AttributeEntity();
                attributeEntity.setMultivalued(false);
                attributeEntity.setName(columnEntity.getColumnName());
                attributeEntity.setType(columType);
                attributeEntity.setRequired(columnEntity.getIsNullable() == 0);
                if (columnEntity.getColumnName().equals("account")){
                    // account为bim系统关键字，不允许使用
                    attributeEntity.setName("userAccount");
                }
                tables.add(attributeEntity);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return tables;
    }
}
